import { FormInstance } from 'antd';
import debounce from 'lodash/debounce';
import { makeAutoObservable, runInAction } from 'mobx';
import cityApi from '../../api/cityApi';
import companyApi from '../../api/companyApi';

interface Option {
  value: string;
  label: string;
  children?: Option[];
  disabled?: boolean;
};

export default class Company {

  loading: boolean;
  saving: boolean;
  data: any[];
  cityOptions: Option[];
  record: any;
  current: number;
  pageSize: number;
  total: number;
  conditions: object;

  constructor() {
    this.loading = false;
    this.saving = false;
    this.data = [];
    this.cityOptions = [];
    this.record = null;
    this.current = 0;
    this.pageSize = 10;
    this.total = 0;
    this.conditions = this.getDefaultConditions();
    makeAutoObservable(this);
  }

  async fetchData(keyword: string, city: any, active: string, owner: string, pageNumber: number) {
    if (this.loading) {
      return;
    }

    const cityId: string = city ? city[city.length - 1] : '';
    runInAction(() => {
      this.loading = true;
    });
    const [res, cityRes] = await Promise.all([
      companyApi.query(keyword, cityId, active, owner, pageNumber, this.pageSize),
      cityApi.findAll()
    ]);
    const data: any = (res as any).data || {};
    const list: any[] = data.list || [];
    list.forEach((item: any) => {
      for (let prop in item.company) {
        item[prop] = item.company[prop];
      }
      if (item.city) {
        item.cityName = item.city.city.name;
        if (item.city.parent) {
          item.provinceId = item.city.parent.id;
          item.provinceName = item.city.parent.name;
        }
      }
    });
    this.selectRecord(null);
    runInAction(() => {
      this.data = list;
      this.cityOptions = this.getOptions(cityRes);
      this.current = data.current || 0;
      this.total = data.total || 0;
      this.loading = false;
      this.conditions = {
        keyword,
        city,
        active,
        owner,
        pageNumber
      };
    });
  }

  saveData(values: any) {
    this.setSaving(true);
    const id: string = this.record ? this.record.id : null;
    const data: any = {
      id,
      ...values
    };
    return companyApi.save(data);
  }

  deleteData() {
    return companyApi.delete(this.record ? this.record.id : '<empty>');
  }

  getEditRecord() {
    let currentRecord: any = null;
    if (this.record) {
      currentRecord = { ...this.record };
      if (currentRecord.cityId) {
        currentRecord.city = [currentRecord.provinceId, currentRecord.cityId];
      } else {
        currentRecord.city = null;
      }
    } else {
      currentRecord = {
        name: '',
        city: null,
        cityId: null,
        active: true,
        address: '',
        website: '',
        email: '',
        telephone: '',
        remark: '',
        logo: null,
        logoId: null
      }
    }
    return currentRecord;
  }

  getOptions(res: any) {
    const list: any[] = res.data || [];
    list.unshift({
      city: {
        id: '',
        name: ''
      }
    });
    return list.map(item => {
      return {
        label: item.city.name,
        value: item.city.id,
        children: this.getChildrenOptions(item.children || [])
      };
    });
  }

  getChildrenOptions(children: any[]) {
    return children.map(child => {
      return {
        label: child.name,
        value: child.id
      };
    });
  }

  selectRecord(record: any) {
    runInAction(() => {
      this.record = record
    });
  }

  setPageSize(pageSize: number) {
    runInAction(() => {
      this.pageSize = pageSize;
    });
  }

  setSaving(saving: boolean) {
    runInAction(() => {
      this.saving = saving;
    });
  }

  getDefaultConditions() {
    return {
      keyword: '',
      city: null,
      active: '',
      owner: '',
      pageNumber: 0
    };
  }

  resetConditions(form: FormInstance<any>) {
    runInAction(() => {
      this.conditions = this.getDefaultConditions();
      debounce(() => form.resetFields(), 50)();
    });
  }

  setConditions(conditions: any) {
    runInAction(() => {
      this.conditions = conditions;
    });
  }

};
